/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package server;

import core.Graph;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

/**
 *
 * @author Alexey Chirkov
 */
class GraphImpl implements Graph {

    double[][] filter = {{1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0},
        {1.0 / 9.0, 1.0 / 9.0, 1.0 / 9.0},
        {1.0 / 9.0,1.0 / 9.0, 1.0 / 9.0}};
    int width = 3, height = 3;
    int centerX = 1, centerY = 1;

    @Override
    public byte[] execute(byte[] image) throws RemoteException {
        System.out.print("Run");
        BufferedImage sourceImage = null;
        try {
            sourceImage = ImageIO.read(new ByteArrayInputStream(image));
        } catch (IOException ex) {
            Logger.getLogger(GraphImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
        BufferedImage destImage = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), sourceImage.getType());

        Raster srcRaster = sourceImage.getData();
        WritableRaster destRaster = destImage.getRaster();

        int iWidth = sourceImage.getWidth();
        int iHeight = sourceImage.getHeight();
        int bandCount = srcRaster.getNumBands();
        double[] src = new double[iWidth * iHeight];
        double[] dest = new double[iWidth * iHeight];

        int i, j, b, fi, fj, cx, cy;
        double v;
        for (b = 0; b < bandCount; b++) {
            srcRaster.getSamples(0, 0, iWidth, iHeight, b, src);
            for (i = 0; i < iHeight; i++) {
                for (j = 0; j < iWidth; j++) {
                    v = 0.0;
                    for (fi = 0; fi < width; fi++) {
                        for (fj = 0; fj < height; fj++) {
                            if (filter[fi][fj] != 0) {
                                cx = j - centerX + fj;
                                cy = i - centerY + fi;
                                if ((cx >= 0) && (cx < iWidth) && (cy >= 0) && (cy < iHeight)) {
                                    v += filter[fi][fj] * src[cy * iWidth + cx];
                                } // if(cx,cy)
                            } //if (filter[i][j] != 0)
                        } //for (fi)
                    } //for (fj)
                    if (v < 0.0) {
                        v = 0.0;
                    } else if (v > 255.0) {
                        v = 255.0;
                    }
                    dest[i * iWidth + j] = v;
                } //for (j)
            } //for (i)
            destRaster.setSamples(0, 0, iWidth, iHeight, b, dest);
        } //for (b)
        destImage.setData(destRaster);
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ImageIO.write(destImage, "png", os);
        } catch (IOException ex) {
            Logger.getLogger(GraphImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
        return os.toByteArray();
    }
}